﻿using System;
using XchangeStreamer.OutputSdk.ViewModel;
using System.Collections.Generic;
using System.Threading;
using System.Collections.ObjectModel;

namespace XchangeStreamer.OutputSdk.Internal
{
    [Serializable]
    internal sealed class MarketManager
    {
        #region Private Fields

        private object locker = new object();
        private ObservableCollection<Symbol> symbols;
        private IMarket market;
        
        #endregion

        #region Public Constructors

        public MarketManager()
        {
            this.symbols = new ObservableCollection<Symbol>();
            this.market = new Market(this);
        }

        #endregion

        #region Public Methods

        public void Add(Symbol item)
        {
            lock (this.locker)
            {
                Symbol target = null;
                for (int i = 0; i < this.symbols.Count; i++)
                {
                    if (this.symbols[i].Isin_Code == item.Isin_Code)
                    {
                        target = this.symbols[i];
                        break;
                    }
                }

                if (target == null)
                {
                    this.symbols.Add(item);
                }
                else
                {
                    target.Arb_Name = item.Arb_Name;
                    target.Eng_Name = item.Eng_Name;
                }
            }
        }

        public bool Remove(Symbol item)
        {
            lock (this.locker)
            {
                return this.symbols.Remove(item);
            }
        }

        public void Clear()
        {
            lock (this.locker)
            {
                this.symbols.Clear();
            }
        }

        #endregion

        #region Public Properties

        public IMarket Current
        {
            get
            {
                return this.market;
            }
        }

        #endregion

        #region Private Methods

        private Symbol Find(string isin_code)
        {
            lock (this.locker)
            {
                Symbol target = null;
                for (int i = 0; i < this.symbols.Count; i++)
                {
                    if (this.symbols[i].Isin_Code == isin_code)
                    {
                        target = this.symbols[i];
                        break;
                    }
                }

                if (target == null)
                {
                    target = new Symbol();
                    target.Isin_Code = isin_code;
                    this.symbols.Add(target);
                }
                return target;
            }
        }

        #endregion

        #region Nested Types

        public class Market : IMarket
        {
            #region Private Fields

            private MarketManager manager;
            private IList<Symbol> symbols;
            private IList<Trade> trades;

            #endregion
            
            #region Constructors

            private Market()
            { }

            internal Market(MarketManager manager)
            {
                this.manager = manager;
                this.symbols = Factory.Create(this.manager.symbols);
            }

            #endregion

            #region IMarket Members

            public Symbol Find(string isin_code)
            {
                return this.manager.Find(isin_code);
            }

            public IList<Symbol> Symbols
            {
                get
                {
                    return this.symbols;
                }
            }

            public IList<Trade> Trades
            {
                get 
                {
                    return this.trades;
                }
            }

            #endregion
        }

        #endregion
    }
}
